﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using Microsoft.SharePoint;

namespace IntelligentDecisioning.SharePoint.Definition.Fields
{
    /// <summary>
    /// Base class for defining fields in a sharepoint list or as site columns
    /// </summary>
    public class Field
    {
        #region Properties

        public String Id { get; set; }
        public String Name { get; set; }
        public String DisplayName { get; set; }
        public String Type { get; set; }
        public String GroupName { get; set; }
        public String StaticName { get; set; }
        public bool ReadOnly { get; set; }
        public bool Required { get; set; }
        public String AuthoringInfo { get; set; }
        public bool Filterable { get; set; }
        public bool Hidden { get; set; }
        public bool Sortable { get; set; }
        public String DefaultValue { get; set; }

        // Defines the scope of a site column - ignored when the column is being added to a list directly
        public Scope SiteColumnScope { get; set; }

        // Used to explicityl indicate that this field should be defined as a site column
        public bool IsSiteColumn { get; set; }

        // Used to indicate that a site column should be deleted when the feature that installed it is deactivated
        public bool DeleteSiteColumnOnDeactivation { get; set; }
       
        #endregion

        #region Constructors

        public Field()
        {
            Id = Guid.NewGuid().ToString();
            Type = SPFieldType.Text.ToString();
            IsSiteColumn = false;
            SiteColumnScope = Scope.SiteCollection;
        }

        public Field(String id, String name, String displayName, String type, String groupName, string staticName)
            :this()
        {
            Id = id;
            Name = name;
            DisplayName = displayName;
            Type = type;
            GroupName = groupName;
            StaticName = staticName;
        }

        #endregion

        #region Methods

        public void SetAllNameFields(string name)
        {
            Name = name;
            DisplayName = name;
            StaticName = name;
        }


        /// <summary>
        /// Fields are provisioned by generating a CAML fragment as this apprears to allow options
        /// whihc are not currently available through the Sharepoint object model, e.g, defining the guid for the field
        /// </summary>
        /// <returns></returns>
        internal string GetProvisioningXML()
        {
            StringWriter sw = new StringWriter();
            XmlWriter xmlWriter = XmlTextWriter.Create(sw);

            // <Field
            xmlWriter.WriteStartElement(DefinitionConstants.FIELD_ELEMENT);
            
            xmlWriter.WriteAttributeString(DefinitionConstants.ID_ATTRIBUTE, Id);
            xmlWriter.WriteAttributeString(DefinitionConstants.NAME_ATTRIBUTE, Name);
            xmlWriter.WriteAttributeString(DefinitionConstants.TYPE_ATTRIBUTE, Type);
            xmlWriter.WriteAttributeString(DefinitionConstants.REQUIRED_ATTRIBUTE, Required.ToString());
            xmlWriter.WriteAttributeString(DefinitionConstants.READONLY_ATTRIBUTE, ReadOnly.ToString());

    // Display Name
            if (string.IsNullOrEmpty(DisplayName) == false)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.DISPLAYNAME_ATTRIBUTE, DisplayName);
            }
    // Group Name            
            if(string.IsNullOrEmpty(GroupName) == false)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.GROUPNAME_ATTRIBUTE, GroupName);
            }
    //Static Name
            if (String.IsNullOrEmpty(StaticName) == false)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.STATICNAME_ATTRIBUTE, StaticName);
            }

    //Authoring Info
            if(String.IsNullOrEmpty(AuthoringInfo) == false)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.AUTHORINGINFO_ATTRIBUTE, AuthoringInfo);
            }
  
    // Filterable

            if (Filterable)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.FILTERABLE_ATTRIBUTE, DefinitionConstants.TRUE);
            }
   
    // Hidden

            if (Hidden)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.HIDDEN_ATTRIBUTE, DefinitionConstants.TRUE);
            }

    // Sortable

            if (Sortable)
            {
                xmlWriter.WriteAttributeString(DefinitionConstants.SORTABLE_ATTRIBUTE, DefinitionConstants.TRUE);
            }



            AddCustomFieldAttributes(xmlWriter);

    // Default Value
            if (String.IsNullOrEmpty(DefaultValue)== false)
            {
                xmlWriter.WriteElementString(DefinitionConstants.DEFAULT_ELEMENT, DefaultValue);
            }

            xmlWriter.WriteEndElement(); // End of field element
            xmlWriter.Flush();
            return sw.ToString();
        }

        protected virtual void AddCustomFieldAttributes(XmlWriter xmlWriter)
        {
            ;
            // base classes add their custom attributed here
        }

        #endregion
    }
}
